// 人脸识别服务工具类
const API_CONFIG = require('./api.js').API_CONFIG;
const ReferenceImageManager = require('./referenceImageManager.js');

// 人脸识别API配置
const FACE_API_CONFIG = {
  // 人脸对比接口地址（需要两张图片）
  COMPARE_URL: 'http://localhost:1001/face/compare',
  // 阈值信息接口地址
  THRESHOLD_INFO_URL: 'http://localhost:1001/face/threshold-info',
  // 默认对比阈值（与后端保持一致）
  DEFAULT_THRESHOLD: 80,
  // 请求超时时间
  REQUEST_TIMEOUT: 30000,
  // 最大重试次数
  MAX_RETRIES: 3,
  // 参考图片URL（用于显示说明）
  REFERENCE_IMAGE_URL: 'http://123.56.17.253:9090/2411a-group-three/article/1eaf7de8-6dc8-43d0-9838-411cbd1f975b.jpg'
};

/**
 * 人脸识别服务类
 */
class FaceService {
  
  /**
   * 将图片文件转换为Base64编码
   * @param {string} filePath 图片文件路径
   * @returns {Promise<string>} Base64编码的图片数据
   */
  static async imageToBase64(filePath) {
    return new Promise((resolve, reject) => {
      wx.getFileSystemManager().readFile({
        filePath: filePath,
        encoding: 'base64',
        success: (res) => {
          resolve(res.data);
        },
        fail: (error) => {
          console.error('图片转Base64失败:', error);
          reject(new Error('图片处理失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 验证图片文件
   * @param {string} filePath 图片文件路径
   * @returns {Promise<Object>} 验证结果
   */
  static async validateImage(filePath) {
    return new Promise((resolve, reject) => {
      wx.getFileInfo({
        filePath: filePath,
        success: (res) => {
          // 检查文件大小（限制为5MB）
          const maxSize = 5 * 1024 * 1024; // 5MB
          if (res.size > maxSize) {
            reject(new Error('图片文件过大，请选择小于5MB的图片'));
            return;
          }
          
          // 检查文件格式
          const validExtensions = ['.jpg', '.jpeg', '.png', '.bmp'];
          const hasValidExtension = validExtensions.some(ext => 
            filePath.toLowerCase().includes(ext)
          );
          
          if (!hasValidExtension) {
            reject(new Error('不支持的图片格式，请选择JPG、PNG或BMP格式'));
            return;
          }
          
          resolve({
            size: res.size,
            valid: true
          });
        },
        fail: (error) => {
          reject(new Error('图片文件验证失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 压缩图片（如果需要）
   * @param {string} filePath 图片文件路径
   * @returns {Promise<string>} 压缩后的图片路径
   */
  static async compressImage(filePath) {
    return new Promise((resolve, reject) => {
      wx.compressImage({
        src: filePath,
        quality: 80, // 压缩质量
        success: (res) => {
          resolve(res.tempFilePath);
        },
        fail: (error) => {
          console.warn('图片压缩失败，使用原图:', error);
          resolve(filePath); // 压缩失败时使用原图
        }
      });
    });
  }

  /**
   * 人脸识别 - 与预设参考图片对比
   * @param {string} userImagePath 用户图片文件路径
   * @returns {Promise<Object>} 识别结果
   */
  static async recognizeFace(userImagePath) {
    try {
      console.log('=== 开始人脸识别流程 ===');
      console.log('用户图片路径:', userImagePath);
      
      // 1. 验证图片文件
      console.log('1. 验证图片文件...');
      await this.validateImage(userImagePath);
      console.log('✅ 图片验证通过');
      
      // 2. 压缩图片（如果需要）
      console.log('2. 压缩图片...');
      const compressedImagePath = await this.compressImage(userImagePath);
      console.log('✅ 图片压缩完成');
      
      // 3. 将用户图片转换为Base64
      console.log('3. 转换用户图片为Base64...');
      const userImageBase64 = await this.imageToBase64(compressedImagePath);
      console.log('✅ 用户图片Base64转换完成，长度:', userImageBase64.length);
      
      // 4. 获取参考图片Base64
      console.log('4. 获取参考图片...');
      const referenceImageBase64 = await ReferenceImageManager.getReferenceImageBase64();
      console.log('✅ 参考图片获取完成，长度:', referenceImageBase64.length);
      
      // 5. 调用人脸对比API（带重试机制）
      console.log('5. 调用后端人脸对比API...');
      const result = await this.callCompareAPIWithRetry(userImageBase64, referenceImageBase64);
      console.log('✅ 人脸对比API调用完成');
      
      return {
        success: true,
        data: result,
        message: '人脸识别完成',
        referenceImageUrl: FACE_API_CONFIG.REFERENCE_IMAGE_URL
      };
    } catch (error) {
      console.error('❌ 人脸识别失败:', error);
      return {
        success: false,
        error: error.message || '人脸识别失败',
        message: '人脸识别失败，请重试'
      };
    }
  }

  /**
   * 调用人脸对比API
   * @param {string} userImageBase64 用户图片的Base64编码
   * @param {string} referenceImageBase64 参考图片的Base64编码
   * @returns {Promise<Object>} API响应结果
   */
  static async callCompareAPI(userImageBase64, referenceImageBase64) {
    return new Promise((resolve, reject) => {
      console.log('=== 人脸对比API调用开始 ===');
      console.log('API URL:', FACE_API_CONFIG.COMPARE_URL);
      console.log('用户图片Base64长度:', userImageBase64 ? userImageBase64.length : 0);
      console.log('参考图片Base64长度:', referenceImageBase64 ? referenceImageBase64.length : 0);
      
      wx.request({
        url: FACE_API_CONFIG.COMPARE_URL,
        method: 'POST',
        data: {
          img1Base64: userImageBase64,
          img2Base64: referenceImageBase64
        },
        header: {
          'content-type': 'application/x-www-form-urlencoded'
        },
        timeout: FACE_API_CONFIG.REQUEST_TIMEOUT,
        success: (res) => {
          console.log('人脸对比API响应状态:', res.statusCode);
          console.log('人脸对比API响应数据:', res.data);
          
          if (res.statusCode === 200) {
            try {
              // 检查响应是否为HTML页面
              if (typeof res.data === 'string' && res.data.includes('<!doctype html>')) {
                console.error('❌ 收到HTML响应，可能是服务未启动或URL错误');
                console.error('响应内容预览:', res.data.substring(0, 200) + '...');
                reject(new Error('后端服务未启动或URL配置错误，请检查服务状态'));
                return;
              }
              
              const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
              console.log('解析后的结果:', result);
              
              // 检查API返回的业务状态
              if (result.success === false) {
                console.error('API业务错误:', result);
                reject(new Error(result.user_message || result.error_msg || result.error || '对比失败'));
              } else {
                console.log('✅ 人脸对比成功');
                console.log('相似度分数:', result.score);
                console.log('是否匹配:', result.isMatch);
                console.log('匹配阈值:', result.threshold);
                resolve(result);
              }
            } catch (parseError) {
              console.error('解析API响应失败:', parseError);
              console.error('原始响应数据类型:', typeof res.data);
              console.error('原始响应数据长度:', res.data ? res.data.length : 0);
              console.error('原始响应数据预览:', res.data ? res.data.substring(0, 200) + '...' : 'null');
              reject(new Error('服务器响应格式错误，请检查后端服务是否正常运行'));
            }
          } else {
            console.error('HTTP错误:', res.statusCode, res.data);
            reject(new Error(`API请求失败: HTTP ${res.statusCode}`));
          }
        },
        fail: (error) => {
          console.error('人脸对比API请求失败:', error);
          reject(new Error('网络请求失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 带重试机制的人脸对比API调用
   * @param {string} userImageBase64 用户图片的Base64编码
   * @param {string} referenceImageBase64 参考图片的Base64编码
   * @param {number} maxRetries 最大重试次数
   * @returns {Promise<Object>} API响应结果
   */
  static async callCompareAPIWithRetry(userImageBase64, referenceImageBase64, maxRetries = FACE_API_CONFIG.MAX_RETRIES) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        console.log(`第${i + 1}次尝试调用人脸对比API...`);
        const result = await this.callCompareAPI(userImageBase64, referenceImageBase64);
        console.log(`第${i + 1}次尝试成功`);
        return result;
      } catch (error) {
        console.error(`第${i + 1}次尝试失败:`, error.message);
        
        if (i === maxRetries - 1) {
          // 最后一次尝试失败
          throw error;
        }
        
        // 等待后重试
        const waitTime = 1000 * (i + 1); // 递增等待时间
        console.log(`等待${waitTime}ms后重试...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
      }
    }
  }

  /**
   * 获取人脸识别阈值信息
   * @returns {Promise<Object>} 阈值信息
   */
  static async getThresholdInfo() {
    return new Promise((resolve, reject) => {
      wx.request({
        url: FACE_API_CONFIG.THRESHOLD_INFO_URL,
        method: 'GET',
        timeout: 10000,
        success: (res) => {
          if (res.statusCode === 200) {
            try {
              const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
              resolve(result);
            } catch (parseError) {
              console.error('解析阈值信息失败:', parseError);
              reject(new Error('服务器响应格式错误'));
            }
          } else {
            reject(new Error(`获取阈值信息失败: HTTP ${res.statusCode}`));
          }
        },
        fail: (error) => {
          console.error('获取阈值信息失败:', error);
          reject(new Error('网络请求失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 拍照获取图片
   * @returns {Promise<string>} 图片临时文件路径
   */
  static async takePhoto() {
    return new Promise((resolve, reject) => {
      wx.chooseMedia({
        count: 1,
        mediaType: ['image'],
        sourceType: ['camera'],
        camera: 'front', // 前置摄像头
        success: (res) => {
          if (res.tempFiles && res.tempFiles.length > 0) {
            resolve(res.tempFiles[0].tempFilePath);
          } else {
            reject(new Error('未获取到图片'));
          }
        },
        fail: (error) => {
          console.error('拍照失败:', error);
          reject(new Error('拍照失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 从相册选择图片
   * @returns {Promise<string>} 图片临时文件路径
   */
  static async chooseImageFromAlbum() {
    return new Promise((resolve, reject) => {
      wx.chooseMedia({
        count: 1,
        mediaType: ['image'],
        sourceType: ['album'],
        success: (res) => {
          if (res.tempFiles && res.tempFiles.length > 0) {
            resolve(res.tempFiles[0].tempFilePath);
          } else {
            reject(new Error('未选择图片'));
          }
        },
        fail: (error) => {
          console.error('选择图片失败:', error);
          reject(new Error('选择图片失败: ' + error.errMsg));
        }
      });
    });
  }

  /**
   * 显示人脸识别结果
   * @param {Object} result 识别结果
   */
  static showRecognitionResult(result) {
    if (result.success) {
      const data = result.data;
      const score = data.score || 0;
      const isMatch = data.isMatch || false;
      const threshold = data.threshold || FACE_API_CONFIG.DEFAULT_THRESHOLD;
      
      let title = '';
      let content = '';
      let icon = '';
      
      if (isMatch) {
        title = '识别成功';
        content = `相似度: ${score.toFixed(1)}分\n确认为同一人`;
        icon = 'success';
      } else {
        title = '识别失败';
        content = `相似度: ${score.toFixed(1)}分\n不是同一人（需要${threshold}分以上）`;
        icon = 'none';
      }
      
      wx.showModal({
        title: title,
        content: content,
        showCancel: false,
        confirmText: '知道了',
        confirmColor: isMatch ? '#4CAF50' : '#FF5722'
      });
    } else {
      wx.showModal({
        title: '识别失败',
        content: result.message || '人脸识别失败，请重试',
        showCancel: false,
        confirmText: '知道了',
        confirmColor: '#FF5722'
      });
    }
  }

  /**
   * 获取识别结果等级
   * @param {number} score 相似度分数
   * @returns {Object} 等级信息
   */
  static getScoreLevel(score) {
    if (score >= 90) {
      return {
        level: 'excellent',
        text: '极佳',
        color: '#4CAF50',
        description: '相似度极高，几乎确定是同一人'
      };
    } else if (score >= 80) {
      return {
        level: 'good',
        text: '良好',
        color: '#8BC34A',
        description: '相似度很高，很可能是同一人'
      };
    } else if (score >= 60) {
      return {
        level: 'medium',
        text: '中等',
        color: '#FF9800',
        description: '相似度中等，可能是同一人'
      };
    } else if (score >= 40) {
      return {
        level: 'low',
        text: '较低',
        color: '#FF5722',
        description: '相似度较低，可能不是同一人'
      };
    } else {
      return {
        level: 'very-low',
        text: '很低',
        color: '#F44336',
        description: '相似度很低，基本确定不是同一人'
      };
    }
  }

  /**
   * 保存识别记录到本地
   * @param {Object} result 识别结果
   * @param {string} imagePath 图片路径
   */
  static saveRecognitionRecord(result, imagePath) {
    try {
      const records = wx.getStorageSync('faceRecognitionRecords') || [];
      const newRecord = {
        id: Date.now(),
        timestamp: new Date().toISOString(),
        imagePath: imagePath,
        result: result,
        score: result.data?.score || 0,
        isMatch: result.data?.isMatch || false,
        success: result.success
      };
      
      records.unshift(newRecord);
      
      // 只保留最近100条记录
      if (records.length > 100) {
        records.splice(100);
      }
      
      wx.setStorageSync('faceRecognitionRecords', records);
    } catch (error) {
      console.error('保存识别记录失败:', error);
    }
  }

  /**
   * 获取识别记录统计
   * @returns {Object} 统计信息
   */
  static getRecognitionStats() {
    try {
      const records = wx.getStorageSync('faceRecognitionRecords') || [];
      const total = records.length;
      const successful = records.filter(r => r.success).length;
      const matched = records.filter(r => r.isMatch).length;
      const avgScore = records.length > 0 ? 
        records.reduce((sum, r) => sum + (r.score || 0), 0) / records.length : 0;
      
      return {
        total,
        successful,
        matched,
        avgScore: Math.round(avgScore * 10) / 10,
        successRate: total > 0 ? Math.round((successful / total) * 100) : 0,
        matchRate: total > 0 ? Math.round((matched / total) * 100) : 0
      };
    } catch (error) {
      console.error('获取识别统计失败:', error);
      return {
        total: 0,
        successful: 0,
        matched: 0,
        avgScore: 0,
        successRate: 0,
        matchRate: 0
      };
    }
  }

  /**
   * 清除所有识别记录
   */
  static clearAllRecords() {
    try {
      wx.removeStorageSync('faceRecognitionRecords');
      return true;
    } catch (error) {
      console.error('清除识别记录失败:', error);
      return false;
    }
  }

  /**
   * 预加载参考图片
   * @returns {Promise<boolean>} 预加载是否成功
   */
  static async preloadReferenceImage() {
    try {
      console.log('🚀 开始预加载参考图片...');
      await ReferenceImageManager.preloadReferenceImage();
      console.log('✅ 参考图片预加载完成');
      return true;
    } catch (error) {
      console.error('❌ 参考图片预加载失败:', error);
      return false;
    }
  }

  /**
   * 获取参考图片缓存状态
   * @returns {Object} 缓存状态信息
   */
  static getReferenceImageCacheStatus() {
    return ReferenceImageManager.getCacheStatus();
  }

  /**
   * 强制刷新参考图片
   * @returns {Promise<string>} 新的参考图片Base64编码
   */
  static async refreshReferenceImage() {
    try {
      console.log('🔄 强制刷新参考图片...');
      const newImage = await ReferenceImageManager.refreshReferenceImage();
      console.log('✅ 参考图片刷新完成');
      return newImage;
    } catch (error) {
      console.error('❌ 参考图片刷新失败:', error);
      throw error;
    }
  }

  /**
   * 清除参考图片缓存
   */
  static clearReferenceImageCache() {
    ReferenceImageManager.clearCache();
  }
}

module.exports = FaceService;
